var Tests = [
    // Page references from HP-15C Owner's Handbook (November 1985)
//]; var zz = [

    // p13
    ["9\r6-", 3],
    ["9\r6*", 54],
    ["9\r6/", 1.5],
    ["9\r6^", 531441],
    // p14
    ["300.51\r2*9.8/q", 7.8313, 0.0001],

    // Part I Fundamentals
    // p19
    ["123_\r", -123],
    ["1.2e3\r", 1200],
    ["1.2e_3\r", 0.0012],
    // p20
    ["6.6262e34_\r50*", 3.3131e-32, 0.0001],
    ["g\b", 0],
    ["12345", 12345],
    ["\b", 1234],
    ["9", 12349],
    ["q", 111.1261, 0.0001],
    ["\b", 0],
    // p22
    ["45g)", 1.6532, 0.0001],
    // p23
    ["9\r17+4-4/", 5.5],
    ["6\r7+9\r3-*", 78],
    // p24
    ["p", Math.PI],
    ["123.4567gS", 123],
    ["g\r_gS", -123],
    ["g\rfS", -0.4567, 1e-9],
    ["1.23456789_", -1.2346, 0.0001],
    ["gx", -1.2346],
    ["a", 1.2346],
    // p25
    ["25\\", 0.04],
    ["8!", 40320],
    ["3.9q", 1.9748, 0.0001],
    ["12.3@", 151.29, 1e-9],
    // p26
    ["g730s", 0.5, 1e-9],
    ["gs", 30, 1e-9],
    ["60c", 0.5, 1e-9],
    ["gc", 60, 1e-9],
    ["45t", 1, 1e-9],
    ["gt", 45],
    // rad, grad
    // p27
    ["1.2345f2", 1.1404, 0.0001],
    ["g2", 1.2345, 1e-9],
    ["40.5f3", 0.7069, 0.0001],
    ["g3", 40.5],
    // p28
    ["45l", 3.8067, 0.0001],
    ["3.4012E", 30.0001, 0.0001],
    ["12.4578g)", 1.0954, 0.0001],
    ["3.1354)", 1365.8405, 1e-6],
    // hyp functions
    // p29
    ["2\r1.4^", 2.6390, 0.0001],
    ["2\r1.4_^", 0.3789, 0.0001],
    ["2_\r3^", -8],
    ["2\r3\\^", 1.2599, 0.0001],
    // p30
    ["15.76\r3%+", 16.2328, 0.0001],
    ["15.76\r14.12g\\", -10.4061, 0.0001],
    // p31
    ["g75\r10g1", [11.1803, 26.5651], 0.0001],
    ["30\r12f1", [10.3923, 6], 0.0001],
    // p35
    ["287\r12.9/g\r*13.9/", 20.6475, 0.0001],
    // p41
    ["1.15\r\r\r1000****", 1749.0063, 1e-7],
    // p43
    ["3S0", 3],
    ["g\b", 0],
    ["R0", 3],
    // p45
    ["8S04S+03S+024R-0", 9],
    ["R0", 15],
    ["4\r5.2-8.33*g\r7.46-0.32*/3.15\r2.75-4.3*1.71\r2.01*-/q", 4.5728, 0.0001],
    // p47
    ["5\r3f+", 60],
    // p48
    ["52\r4g+", 270725],
    // p49
    // RAN# [".5764Sf\r"],
    // p51
    ["fU4.63\r0;", 1],
    ["4.78\r20;6.61\r40;7.21\r60;7.78\r80;", 5],
    ["R3", 200],
    ["R4", 12000],
    ["R5", 31.01],
    ["R6", 200.49, 0.0001],
    ["R7", 1415],
    // p52
    ["4.78\r20g;", 4],
    ["5.78\r20;", 5],
    // p53
    ["g0", [40, 6.4], 0.001],
    // p54
    ["g.", [31.62, 1.24], 0.01],
    // p55
    ["f;", [4.86, 0.04], 0.04],
    // p57
    ["70f.", [7.56, 0.99], 0.01],
    // p58
    ["123456f74", "123,456.0000"],
    ["f84", "1.2346e5"],
    // ENG ["f94", "123.46e3"],
    ["123.4567895f74", "123.4568"],
    ["f76", "123.456790"],
    ["f74", "123.4568"],
    ["f86", "1.234568e2"],
    ["f88", "1.23456790e2"],
    // p59
    [".012345f74", 0.012345],
    // ENG ["f91", "12e-3"],
    // ENG ["f93", "12.35e-3"],
    ["10*", .12345], // ENG ["10*", "123.5e-3"],
    ["f74", "0.1235"],
    // p60
    ["p", "3.1416"],
    ["f\b", "3141592653589793"],

    // Part II Programming
    // p67
    ["gP",  "000-"],
    ["fr",  "000-"],
    ["fTq", "001-42,21,11"],
    ["2",   "002-     2"],
    ["*",   "003-    20"],
    ["9",   "004-     9"],
    [".",   "005-    48"],
    ["8",   "006-     8"],
    ["/",   "007-    10"],
    ["q",   "008-    11"],
    ["gU",  "009- 43 32"],
    ["gP"],
    ["300.51", 300.51],
    ["fq", 7.8313, 0.0001],
    // p71
    ["gP"],
    ["fr",  "000-"],
    ["fTq", "001-42,21,11"],
    ["S0",  "002- 44  0"],
    ["gq",  "003- 43 11"],
    ["ge",  "004- 43 26"],
    ["*",   "005-    20"],
    ["S4",  "006- 44  4"],
    ["S+1", "007-44,40, 1"],
    ["P",   "008-    31"],
    ["*",   "009-    20"],
    ["fP",  "010- 42 31"],
    ["S+2", "011-44,40, 2"],
    ["R0",  "012- 45  0"],
    ["/",   "013-    10"],
    ["2",   "014-     2"],
    ["*",   "015-    20"],
    ["R4",  "016- 45  4"],
    ["2",   "017-     2"],
    ["*",   "018-    20"],
    ["+",   "019-    40"],
    ["S+3", "020-44,40, 3"],
    ["gU",  "021- 43 32"],
    ["gP"],
    ["fx"],
    ["2.5", 2.5],
    ["fq", 19.6350, 0.0001],
    ["8P", 164.9336, 0.0001],
    ["4P", 50.2655, 0.0001],
    ["10.5P", 364.4247, 0.0001],
    ["4.5P", 63.6173, 0.0001],
    ["4P", 240.3318, 0.0001],
    ["R1", 133.5177, 0.0001],
    ["R2", 939.3362, 0.0001],
    ["R3", 769.6902, 0.0001],
    // p84 (out of order: edits previous program)
    ["gP"],
    ["G_020",   "020-44,40, 3"],
    ["\b",      "019-    40"],
    ["gTgTgT",  "016- 45  4"],
    ["\b",      "015-    20"],
    ["R2",      "016- 45  2"],
    ["G_011",   "011-44,40, 2"],
    ["\b",      "010- 42 31"],
    ["gTgT",    "008-    31"],
    ["\b",      "007-44,40, 1"],
    ["R1",      "008- 45  1"],
    ["gT",      "007-44,40, 1"],
    ["\b",      "006- 44  4"],
    ["\b",      "005-    20"],
    ["S2",      "006- 44  2"],
    // p86
    ["gP", function() { return !Prgm; }],
    ["fx"],
    ["Gq", function() { return PC === 1; }],
    ["8S1", 8],
    ["2.5", 2.5],
    ["T", 2.5],
    ["T", function() { return Reg[0] === 2.5; }],
    ["T", 6.25],
    ["T", 3.1416, 0.0001],
    ["T", 19.6350, 0.0001],
    // p80
    ["gPfr", "000-"],
    ["fTE", "001-42,21,12"],
    ["5",   "002-     5"],
    ["*",   "003-    20"],
    ["2",   "004-     2"],
    ["+",   "005-    40"],
    ["*",   "006-    20"],
    ["*",   "007-    20"],
    ["*",   "008-    20"],
    ["gU",  "009- 43 32"],
    ["gP"],
    ["7\r\r\r", 7],
    ["fE", 12691],
    // p93
    ["gPfr","000-"],
    ["fTq", "001-42,21,11"],
    ["R0",  "002- 45  0"],
    ["fP",  "003- 42 31"],
    ["8",   "004-     8"],
    ["/",   "005-    10"],
    ["_",   "006-    16"],
    ["2",   "007-     2"],
    ["x",   "008-    34"],
    ["^",   "009-    14"],
    ["R*1", "010-45,20, 1"],
    ["fP",  "011- 42 31"],
    ["R2",  "012- 45  2"],
    ["g-9", "013-43,30, 9"],
    ["gU",  "014- 43 32"],
    ["3",   "015-     3"],
    ["S+0", "016-44,40, 0"],
    ["Gq",  "017- 22 11"],
    ["gP"],
    ["2S0", 2],
    ["100S1", 100],
    ["50S2", 50],
    ["fq", 50],
    // p96
    ["gPfr","000-"],
    ["fTE", "001-42,21,12"],
    ["g50", "002-43, 5, 0"],
    ["G1",  "003- 22  1"],
    ["fT\\","004-42,21,15"],
    ["g40", "005-43, 4, 0"],
    ["fT1", "006-42,21, 1"],
    ["S1",  "007- 44  1"],
    ["1",   "008-     1"],
    ["+",   "009-    40"],
    ["x",   "010-    34"],
    ["_",   "011-    16"],
    ["^",   "012-    14"],
    ["_",   "013-    16"],
    ["1",   "014-     1"],
    ["+",   "015-    40"],
    ["R/1", "016-45,10, 1"],
    ["*",   "017-    20"],
    ["g60", "018-43, 6, 0"],
    ["gU",  "019- 43 32"],
    ["R1",  "020- 45  1"],
    ["1",   "021-     1"],
    ["+",   "022-    40"],
    ["*",   "023-    20"],
    ["gU",  "024- 43 32"],
    ["gP"],
    ["250\r", 250],
    ["48\r", 48],
    [".005", 0.005],
    ["fE", 10698.3049, 0.0001],
    ["250\r", 250],
    ["48\r", 48],
    [".005", 0.005],
    ["f\\", 10645.0795, 0.0001],
    // p103
    ["gPfrfT9g8S0xS-0U.3_xU.3+R/0gUfT.3gqg\rs-gUgP"],
    ["0.52\r1.25U9", 1.1507, 0.0001],
    ["1_\r1U9", -0.8415, 0.0001],
    ["0.81\r0.98U9", 1.1652, 0.0001],
    // p104
    ["gPfrfT.4gqU.5U.5U.5qgUfT.5xgq+gUgP"],
    ["8\r1.3\r7.9\r4.3U.4", 12.1074, 0.0001],
    // p111
    ["fx12.3456", 12.3456],
    ["St", 12.3456],
    ["7q", 2.6458, 0.0001],
    ["Sc", function() { return Reg[12] === Stack[0]; }],
    ["Rt", 12.3456],
    ["Rc", 2.6458, 0.0001],
    ["f4.2", 2.6458, 0.0001],
    // p112
    ["f4t", 12.3456],
    ["Rt", 2.6458, 0.0001],
    ["f4c", 0],
    ["Rc", 2.6458, 0.0001],
    ["f42", 2.6458, 0.0001],
    ["10S+t", 10],
    ["Rt", 12.6458, 0.0001],
    ["geS/c", 3.1416, 0.0001],
    ["Rc", 0.8422, 0.0001],
    ["f4.2", 0.8422, 0.0001],
    // p113
    ["gPfrfTqR0fP8/_2x^R*1fPR2g-9gU3S+0GqgP"],
    ["gP"],
    ["G_013",   "013-43,30, 9"],
    ["\b\b",    "011- 42 31"],
    ["f52",     "012-42, 5, 2"],
    ["Gt",      "013- 22 25"],
    ["gP"],
    ["2S0", 2],
    ["100S1", 100],
    ["3.00001S2", 3.00001],
    ["15_St", -15],
    ["fq", 50],
    // p114
    ["gPfrfTE9StfT0f7tRtfPf5tG0g-1G0gUgP"],
    ["fE", 0],

    // Part III Advanced Functions
    // p121
    ["9\r8\r7\r6f\b"],
    ["2\r3I4\r5I+", new Complex(6, 8)],
    ["\b7-", new Complex(-1, -8)],
    ["f-\b5f-", new Complex(-1, 5)],
    ["\b4\r7I", new Complex(4, 7)],
    ["\b8f-\b9gq", new Complex(17, 144)],
    ["4\r", new Complex(4, 0)],
    ["10f-", new Complex(0, 10)],
    ["1.2\r4.7I2.7\r3.2I/q", new Complex(1.0491, 0.2406), 0.0001],
    // ["2.404gs", new Complex(1.5708, -1.5239), 0.0001],
    // p135
    ["g72\r65If1", 0.8452, 0.0001],
    ["3\r40If1", 2.2981, 0.0001],
    ["+", 3.1434, 0.0001],
    ["g1", new Complex(4.8863, 49.9612), 0.0001],
    // p136
    ["2f-", 0],
    ["8_\r", -8],
    ["6I", -8],
    ["3^", 352],
    ["*", -1872],
    ["4\r", 4],
    ["5q", 2.2361, 0.0001],
    ["2_*", -4.4721, 0.0001],
    ["I", 4],
    ["/", -295.4551, 0.0001],
    ["2\r5q", 2.2361, 0.0001],
    ["4_*", -8.9443, 0.0001],
    ["I", 2],
    ["/", new Complex(9.3982, -35.1344), 0.0001],
    ["g58"],
    // p139
    ["2\rfsq", 2],
    ["f_1", 2],
    ["fR", function() { return User; }],
    ["3.8Sq", "A  1,1"],
    ["7.2Sq", 7.2],
    ["1.3Sq", 1.3],
    [".9_Sq", -0.9],
    ["2\r1fsE", 1],
    ["16.5SE", 16.5],
    ["22.1_SE", -22.1],
    ["fe)", -22.1],
    ["R_E", new MatrixCheck(B, 2, 1)],
    ["R_q", new MatrixCheck(A, 2, 2)],
    ["/", new MatrixCheck(C, 2, 1)],
    ["R)", -11.2887, 0.0001],
    ["R)", 8.2496, 0.0001],
    ["fR", function() { return !User; }],
    ["f_0"],
    // p142
    ["2\r", 2],
    ["3", 3],
    ["fsq", 3],
    ["R_E", new MatrixCheck(B, 0, 0)],
    ["Rsq", [3, 2]],
    // p145
    ["f_1", function() { return Reg[0] === 1 && Reg[1] === 1; }],
    ["fR", function() { return User; }],
    ["1Sq", 1],
    ["2Sq", 2],
    ["3Sq", 3],
    ["4Sq", 4],
    ["5Sq", 5],
    ["6Sq", 6],
    ["Rq", 1],
    ["Rq", 2],
    ["Rq", 3],
    ["Rq", 4],
    ["Rq", 5],
    ["Rq", 6],
    ["fR", 6],
    // p146
    ["2S0", 2],
    ["3S1", 3],
    ["9", 9],
    ["Sq", function() { return g_Matrix[0].get(2, 3) === 9; }],
    // p147
    ["2\r1", 1],
    ["Rgq", 4],
    // p149
    ["R_q", new MatrixCheck(A, 2, 3, [[1, 2, 3], [4, 5, 9]])],
    ["S_E", new MatrixCheck(A, 2, 3, [[1, 2, 3], [4, 5, 9]])],
    ["R_E", new MatrixCheck(B, 2, 3, [[1, 2, 3], [4, 5, 9]])],
    // p151
    ["R_E", new MatrixCheck(B, 2, 3, [[1, 2, 3], [4, 5, 9]])],
    ["f_4", new MatrixCheck(B, 3, 2, [[1, 4], [2, 5], [3, 9]])],
    // p152
    ["feE"],
    ["R_q", new MatrixCheck(A, 2, 3, [[1, 2, 3], [4, 5, 9]])],
    ["2*", new MatrixCheck(B, 2, 3, [[2, 4, 6], [8, 10, 18]])],
    ["1-", new MatrixCheck(B, 2, 3, [[1, 3, 5], [7, 9, 17]])],
    // p153
    ["fe)"],
    ["R_E", new MatrixCheck(B, 2, 3, [[1, 3, 5], [7, 9, 17]])],
    ["R_q", new MatrixCheck(A, 2, 3, [[1, 2, 3], [4, 5, 9]])],
    ["-", new MatrixCheck(C, 2, 3, [[0, 1, 2], [3, 4, 8]])],
    // p155
    ["R_q", new MatrixCheck(A, 2, 3, [[1, 2, 3], [4, 5, 9]])],
    ["R_E", new MatrixCheck(B, 2, 3, [[1, 3, 5], [7, 9, 17]])],
    ["fe)"],
    ["f_5", new MatrixCheck(C, 3, 3, [[29, 39, 73], [37, 51, 95], [66, 90, 168]])],
    // p157
    ["2\rfsq", 2],
    ["f_1", 2],
    ["fR", function() { return User; }],
    ["1Sq", 1],
    ["Sq", 1],
    [".24Sq", 0.24],
    [".86Sq", 0.86],
    ["2\r3fsE", 3],
    ["274SE", 274],
    ["233SE", 233],
    ["331SE", 331],
    ["120.32SE", 120.32],
    ["112.96SE", 112.96],
    ["151.36SE", 151.36],
    ["fe^", 151.36],
    ["R_E", new MatrixCheck(B, 2, 3, [[274, 233, 331], [120.32, 112.96, 151.36]])],
    ["R_q", new MatrixCheck(A, 2, 2, [[1, 1], [0.24, 0.86]])],
    ["/", new MatrixCheck(D, 2, 3)],
    ["R^", 186, 0.0001],
    ["R^", 141, 0.0001],
    ["R^", 215, 0.0001],
    ["R^", 88, 0.0001],
    ["R^", 92, 0.0001],
    ["R^", 116, 0.0001],
    ["fR", function() { return !User; }],
    // p163
    ["f_0"],
    ["2\r4fsq", 4],
    ["f_1"],
    ["fR", function() { return User; }],
    ["4Sq", 4],
    ["3Sq", 3],
    ["7Sq", 7],
    ["2_Sq", -2],
    ["1Sq", 1],
    ["5Sq", 5],
    ["3Sq", 3],
    ["8Sq", 8],
    ["fR", function() { return !User; }],
    ["R_q", new MatrixCheck(A, 2, 4, [[4, 3, 7, -2], [1, 5, 3, 8]])],
    ["f+", new MatrixCheck(A, 4, 2, [[4, 7], [1, 3], [3, -2], [5, 8]])],
    // p165
    ["R_q", new MatrixCheck(A, 4, 2, [[4, 7], [1, 3], [3, -2], [5, 8]])],
    ["f_2", new MatrixCheck(A, 4, 4, [[4, 7, -3, 2], [1, 3, -5, -8], [3, -2, 4, 7], [5, 8, 1, 3]])],
    ["feE"],
    ["\\", new MatrixCheck(B, 4, 4, [[-0.0254, 0.2420, 0.2829, 0.0022], [-0.0122, -0.1017, -0.1691, 0.1315], [-0.2829, -0.0022, -0.0254, 0.2420], [0.1691, -0.1315, -0.0122, -0.1017]], 0.01)],
    ["f_3", new MatrixCheck(B, 4, 2, [[-0.0254, 0.2420], [-0.0122, -0.1017], [-0.2829, -0.0022], [0.1691, -0.1315]], 0.01)],
    // p167
    ["R_q", new MatrixCheck(A, 4, 4, [[4, 7, -3, 2], [1, 3, -5, -8], [3, -2, 4, 7], [5, 8, 1, 3]])],
    ["R_E", new MatrixCheck(B, 4, 2, [[-0.0254, 0.2420], [-0.0122, -0.1017], [-0.2829, -0.0022], [0.1691, -0.1315]], 0.01)],
    ["fe)"],
    ["*", new MatrixCheck(C, 4, 2)],
    ["fR", function() { return User; }],
    ["R)", 1, 0.0001],
    ["R)", 0, 0.0001],
    ["R)", 0, 0.0001],
    ["R)", 1, 0.0001],
    ["R)", 0, 0.0001],
    ["R)", 0, 0.0001],
    ["R)", 0, 0.0001],
    ["R)", 0, 0.0001],
    ["fR", function() { return !User; }],
    // p170
    ["4\r2fsq", 2],
    ["f_1", 2],
    ["fR", function() { return User; }],
    ["10Sq", 10],
    ["0Sq", 0],
    ["Sq", 0],
    ["Sq", 0],
    ["200Sq", 200],
    ["_Sq", -200],
    ["Sq", -200],
    ["170Sq", 170],
    ["4\r1fsE", 1],
    ["0S_E", 0],
    ["5\r1\r", 1],
    ["SgE", 5],
    ["R_E", new MatrixCheck(B, 4, 1, [[5], [0], [0], [0]])],
    ["R_q", new MatrixCheck(A, 4, 2, [[10, 0], [0, 0], [200, -200], [-200, 170]])],
    ["f_2", new MatrixCheck(A, 4, 4)],
    ["fe)"],
    ["/", new MatrixCheck(C, 4, 1)],
    ["g+", new MatrixCheck(C, 2, 2)],
    ["R)", 0.0372, 0.002],
    ["R)", 0.1311, 0.002],
    ["R)", 0.0437, 0.002],
    ["R)", 0.1543, 0.002],
    ["fR", function() { return !User; }],
    ["f_0"],
    // p181
    ["gPfr","000-"],
    ["fT0", "001-42,21, 0"],
    ["3",   "002-     3"],
    ["-",   "003-    30"],
    ["*",   "004-    20"],
    ["1",   "005-     1"],
    ["0",   "006-     0"],
    ["-",   "007-    30"],
    ["gU",  "008- 43 32"],
    ["gP"],
    ["0\r", 0],
    ["10", 10],
    ["f/0", 5],
    ["r", 5],
    ["r", 0],
    ["0\r", 0],
    ["10_", -10],
    ["f/0", -2],
    ["r", -2],
    ["r", 0],
    // p184
    ["gPfr","000-"],
    ["fTq", "001-42,21,11"],
    ["2",   "002-     2"],
    ["0",   "003-     0"],
    ["/",   "004-    10"],
    ["_",   "005-    16"],
    ["E",   "006-    12"],
    ["_",   "007-    16"],
    ["1",   "008-     1"],
    ["+",   "009-    40"],
    ["5",   "010-     5"],
    ["0",   "011-     0"],
    ["0",   "012-     0"],
    ["0",   "013-     0"],
    ["*",   "014-    20"],
    ["x",   "015-    34"],
    ["2",   "016-     2"],
    ["0",   "017-     0"],
    ["0",   "018-     0"],
    ["*",   "019-    20"],
    ["-",   "020-    30"],
    ["gU",  "021- 43 32"],
    ["gP"],
    ["5\r", 5],
    ["6", 6],
    ["f/q", 9.2843, 0.0001],
    ["r", 9.2843, 0.0001],
    ["r", 0, 1e-9],
    // p186
    ["gPfr","000-"],
    ["fT1", "001-42,21, 1"],
    ["g_",  "002- 43 16"],
    ["1",   "003-     1"],
    ["+",   "004-    40"],
    ["gU",  "005- 43 32"],
    ["gP"],
    ["1\r", 1],
    ["1_", -1],
    ["f/1", "Error 8"],
    // p195
    ["gPfr","000-"],
    ["fT0", "001-42,21, 0"],
    ["s",   "002-    23"],
    ["c",   "003-    24"],
    ["gU",  "004- 43 32"],
    ["gP"],
    ["0\r", 0],
    ["ge", 3.1416, 0.0001],
    ["g8", 3.1416, 0.0001],
    ["f*0", 2.4040, 0.0001],
    ["ge", 3.1416, 0.0001],
    ["/", 0.7652, 0.0001],
    // p197
    ["gPfr","000-"],
    ["fT1", "001-42,21, 1"],
    ["s",   "002-    23"],
    ["-",   "003-    30"],
    ["c",   "004-    24"],
    ["gU",  "005- 43 32"],
    ["gP"],
    ["0\r", 0],
    ["ge", 3.1416, 0.0001],
    ["g8", 3.1416, 0.0001],
    ["f*1", 1.3825, 0.0001],
    ["ge/", 0.4401, 0.001],
    // p199
    ["gPfr","000-"],
    ["fT.2","001-42,21,.2"],
    ["s",   "002-    23"],
    ["x",   "003-    34"],
    ["/",   "004-    10"],
    ["gU",  "005- 43 32"],
    ["gP"],
    ["0\r", 0],
    ["2", 2],
    ["g8", 2],
    //["f*.2", 1.6054, 0.0001], // TODO: integrate against limit where function is undefined

    // Page references from HP-15C Advanced Functions Handbook (November 1985)
    // Section 1: Using Solve Effectively
    // p12
    ["fr"],
    ["\b", 0],
    ["gP",  "000-"],
    ["fTq", "001-42,21,11"],
    ["R4",  "002- 45  4"],
    ["*",   "003-    20"],
    ["R3",  "004- 45  3"],
    ["+",   "005-    40"],
    ["*",   "006-    20"],
    ["R2",  "007- 45  2"],
    ["+",   "008-    40"],
    ["*",   "009-    20"],
    ["R1",  "010- 45  1"],
    ["+",   "011-    40"],
    ["*",   "012-    20"],
    ["R0",  "013- 45  0"],
    ["+",   "014-    40"],
    ["gU",  "015- 43 32"],
    ["gP"],
    ["4.2725e8_", 4.2725e-8],
    ["S4", 4.2725e-8],
    ["1.9931_e5_S3", -1.9931e-5],
    ["1.0229e3_S2", 1.0229e-3],
    ["3.7680e1_S1", 3.7680e-1],
    ["2.8806_S0", -2.8806],
    ["1\r32f/q", 7.5137, 0.0001],
    ["r", 7.5137, 0.0001],
    ["r", 0],
    ["grgr", 7.5137, 0.0001],
    ["fS", 0.5137, 0.0001],
    ["24*", 12.3293, 0.0001],
    ["f2", 12.1945, 0.0001],
    ["1000_\r1100_", -1100],
    ["f/q", -108.9441, 0.0001],
    ["r", -108.9441, 0.0001],
    ["r", 0, 0.0001],
    // p18
    ["gP"],
    ["fr",  "000-"],
    ["fT0", "001-42,21, 0"],
    ["c",   "002-    24"],
    ["R0",  "003- 45  0"],
    ["*",   "004-    20"],
    ["c",   "005-    24"],
    ["R1",  "006- 45  1"],
    ["-",   "007-    30"],
    ["x",   "008-    34"],
    ["s",   "009-    23"],
    ["/",   "010-    10"],
    ["x",   "011-    34"],
    ["t",   "012-    25"],
    ["/",   "013-    10"],
    ["_",   "014-    16"],
    ["x",   "015-    34"],
    ["c",   "016-    24"],
    ["R0",  "017- 45  0"],
    ["*",   "018-    20"],
    ["s",   "019-    23"],
    ["R0",  "020- 45  0"],
    ["*",   "021-    20"],
    ["+",   "022-    40"],
    ["R2",  "023- 45  2"],
    ["*",   "024-    20"],
    ["gU",  "025- 43 32"],
    ["gP"],
    ["g8"],
    ["2p*", 6.2832, 0.0001],
    [".6*S0", 3.7699, 0.0001],
    ["cS1", -0.8090, 0.0001],
    ["_1+", 1.8090, 0.0001],
    ["\\S2", 0.5528, 0.0001],
    ["10f3", 0.1745, 0.001],
    ["60f3", 1.0472, 0.0001],
    ["f/0", 0.4899, 0.0001],
    ["rr", 0, 1e-9],
    ["grgr", 0.4899, 0.0001],
    ["g3", 28.0680, 0.0001],
    // p21
    ["gPfrfTqe_3+\rUExe_3-\rUE-2e_3/gUfTEcR0*cR1-xs/R2*gUgP"],
    ["10f3", 0.1745, 0.001],
    ["60f3", 1.0472, 0.0001],
    ["f/q", 0.4899, 0.0001],
    ["rr", 0, 1e-9],
    ["grgr", 0.4899, 0.0001],
    ["\r\rfE", -0.2043, 0.001],
    ["x", 0.4899, 0.0001],
    ["g3", 28.0679, 0.0001],
    // p29
    ["gPfrfTqS1PU1g\rR*0R5x-g\rR+3g*G0/_g-4G0lR6l/S1gU"],
    ["fTES2P.2\re_3g51f/3G4G0"],
    ["fT4e2*S2gU"],
    ["fT)S3PU1U2_S3gU"],
    ["fT^S4P1S4U1R3U2x/_S4gU"],
    ["fT\\S5PU1R+3R/7_S5gU"],
    ["fT1g411R2%fT3S81S0+g-4G0S6g60S0R1_^S71x-g*G0R*0R4R/8*g61gU"],
    ["R+3fT2R5R*7+gUgP"],
    // p34
    ["fxf72fRg50"],
    ["9\r12*fq", 108],
    ["5.75\r12/fE", 0.48, 0.002],
    ["155_f)", -155],
    ["f\\P", 259.74, 0.001],
    ["275f\\", 275],
    // TODO: off by 100x? ["fEP", 0.53, 0.01],
    // TODO ["12*", 6.39, 0.01],
    // p35
    ["fx"],
    ["30\r12*fq", 360],
    ["13\r12/fE", 1.08, 0.01],
    ["30000f)", 30000],
    ["f^P", -331.86, 0.001],
    // p36
    ["fx"],
    ["36fq", 36],
    ["10\r12/fE", 0.83, 0.01],
    ["3600_f)", -3600],
    ["100f^", 100],
    ["f\\P", 675.27, 0.0001],
    // p37
    ["fx"],
    ["360fq", 360],
    ["14\r12/fE", 1.17, 0.01],
    ["50000_f)", -50000],
    ["f^P", 592.44, 0.0001],
    ["24fq", 24],
    ["f\\P", 49749.56, 0.0001],
    ["St", 49749.56, 0.0001],
    ["12fq", 12],
    ["f\\P", 49883.48, 0.0001],
    ["Rt", 49749.56, 0.0001],
    ["-", 133.92, 0.0001],
    ["R4", 592.44, 0.0001],
    ["12*", 7109.23, 0.0001],
    ["x-", 6975.31, 0.0001],
    // p38
    ["fxg40"],
    ["5\r12*fq", 60],
    ["13\r12/fE", 1.08, 0.01],
    ["63000_f)", -63000],
    ["10000f\\", 10000],
    ["f^P", 1300.16, 0.0001],
    ["70000_f)", -70000],
    ["f^P", 1457.73, 0.0001],
    ["1500f^", 1500],
    // TODO ["fEP", 1.18, 0.01],
    // TODO ["12*", 14.12, 0.01],
    ["fR"],
    // p40
    ["gPfrfTqe2/U2PfTE1\re_3f/2G1G0fT1e2*PfT2g50S21S4+g-4G0S30S5f_1fT3g60G7U6R2g*G41+U6_^S41x-R/2R*3G5fT4xU6fT5*S+5R4S*3G3fT6fRR)fRgUg40gUfT7R5gU", "068- 43 32"],
    ["gPf72"],
    // TODO: DIM ["5fsc", 5],
    ["6\r2", 2],
    ["fs)", 2],
    ["f_1", 2],
    ["fR", function() { return User; }],
    ["80000_S)", -80000],
    ["1S)", 1],
    ["600_S)", -600],
    ["1S)", 1],
    ["6500S)", 6500],
    ["1S)", 1],
    ["8000S)", 8000],
    ["2S)", 2],
    ["7500S)", 7500],
    ["2S)", 2],
    ["91000S)", 91000],
    ["1S)", 1],
    ["9", 9],
    // TODO: this takes a long time to run ["fq", -4108.06, 0.0001],
    // TODO: this takes a long time to run ["fE", 8.04, 0.001],
    // p44
    ["3\r2", 2],
    ["fs)", 2],
    ["f_1", 2],
    ["620000000_", -620000000],
    ["S)", -620000000],
    ["1S)", 1],
    ["100000000S)", 100000000],
    ["10S)", 10],
    ["5000000S)", 5000000],
    ["5S)", 5],
    // TODO: this takes a long time to run ["fE", 10.06],
    ["f74"],
    ["fR", function() { return !User; }],
    // Section 2: Working with Integration
    // Section 3: Calculating in Complex Mode
    // p66
    ["gPfr","000-"],
    ["fTq", "001-42,21,11"],
    ["6",   "002-     6"],
    ["St",  "003- 44 25"],
    ["x",   "004-    34"],
    ["\r",  "005-    36"],
    ["\r",  "006-    36"],
    ["\r",  "007-    36"],
    ["R6",  "008- 45  6"],
    ["fT1", "009-42,21, 1"],
    ["+",   "010-    40"],
    ["Rc",  "011- 45 24"],
    ["x",   "012-    34"],
    ["/",   "013-    10"],
    ["f5t", "014-42, 5,25"],
    ["G1",  "015- 22  1"],
    ["R0",  "016- 45  0"],
    ["+",   "017-    40"],
    ["x",   "018-    34"],
    ["-",   "019-    30"],
    ["g\r", "020- 43 36"],
    ["gE",  "021- 43 12"],
    ["g\r", "022- 43 36"],
    [".",   "023-    48"],
    ["5",   "024-     5"],
    ["-",   "025-    30"],
    ["*",   "026-    20"],
    ["+",   "027-    40"],
    ["gU",  "028- 43 32"],
    ["gP"],
    ["2p*", 6.2832, 0.0001],
    ["gE2/", 0.9189, 0.0001],
    ["S0", 0.9189, 0.0001],
    ["12\\S1", 0.0833, 0.001],
    ["30\\S2", 0.0333, 0.002],
    ["53\r210/S3", 0.2524, 0.0001],
    ["195\r371/S4", 0.5256, 0.0001],
    ["1.011523068S5", 1.0115, 0.0001],
    ["1.517473649S6", 1.5175, 0.0001],
    ["4.2fq", 2.0486, 0.0001],
    ["f79", 2.048555637, 1e-9],
    ["3.2f0", 7.756689536, 1e-9],
    ["gE", 2.048555637, 1e-9],
    ["1\r", 1],
    ["5I", new Complex(1, 5)],
    ["fq", new Complex(-6.130324145, 3.815898575), 1e-9],
    // p76
    ["gPfr","000-"],
    ["fT^", "001-42,21,14"],
    ["f_1", "002-42,16, 1"],
    ["S0",  "003- 44  0"],
    ["r",   "004-    33"],
    ["0",   "005-     0"],
    ["+",   "006-    40"],
    ["fRS)","007u 44 13"],
    ["fR"],
    ["f-",  "008- 42 30"],
    ["S)",  "009- 44 13"],
    ["f-",  "010- 42 30"],
    ["gU",  "011- 43 32"],
    ["fT\\", "012-42,21,15"],
    ["S0",  "013- 44  0"],
    ["g\b", "014- 43 35"],
    ["2",   "015-     2"],
    ["S1",  "016- 44  1"],
    ["r",   "017-    33"],
    ["0",   "018-     0"],
    ["+",   "019-    40"],
    ["R)",  "020- 45 13"],
    ["f-",  "021- 42 30"],
    ["f51", "022-42, 5, 1"],
    ["g\b", "023- 43 35"],
    ["R)",  "024- 45 13"],
    ["gU",  "025- 43 32"],
    ["gP"],
    ["5\r2", 2],
    ["fs)", 2],
    ["2\r3I", new Complex(2, 3)],
    ["1f^", 2],
    ["7\r4I", new Complex(7, 4)],
    ["2f^", 7],
    ["1f\\", new Complex(2, 3)],
    ["2f\\", new Complex(7, 4)],
    ["+", new Complex(9, 7)],
    // p78
    ["gPfr","000-"],
    ["fTq", "001-42,21,11"],
    ["x",   "002-    34"],
    ["\\",  "003-    15"],
    ["g\r", "004- 43 36"],
    ["r",   "005-    33"],
    ["g48", "006-43, 4, 8"],
    ["^",   "007-    14"],
    ["S2",  "008- 44  2"],
    ["f-",  "009- 42 30"],
    ["S3",  "010- 44  3"],
    ["3",   "011-     3"],
    ["6",   "012-     6"],
    ["0",   "013-     0"],
    ["gr",  "014- 43 33"],
    ["/",   "015-    10"],
    ["S4",  "016- 44  4"],
    ["0",   "017-     0"],
    ["St",  "018- 44 25"],
    ["fT0", "019-42,21, 0"],
    ["R4",  "020- 45  4"],
    ["R*t", "021-45,20,25"],
    ["f-",  "022- 42 30"],
    ["g\b", "023- 43 35"],
    ["1",   "024-     1"],
    ["g7",  "025- 43  7"],
    ["f1",  "026- 42  1"],
    ["R2",  "027- 45  2"],
    ["R3",  "028- 45  3"],
    ["ft",  "029- 42 25"],
    ["*",   "030-    20"],
    ["Rt",  "031- 45 25"],
    ["x",   "032-    34"],
    ["1",   "033-     1"],
    ["S+t", "034-44,40,25"],
    ["r",   "035-    33"],
    ["P",   "036-    31"],
    ["G0",  "037- 22  0"],
    ["gP"],
    ["100\r1", 1],
    ["fq", new Complex(1, 0)],
    ["P", new Complex(0.9980, 0.0628), 0.001],
    ["50St", 50],
    ["P", new Complex(-1, 0), 0.0001],
    // p82
    ["gPfr"],
    ["fTqg58\r+.5+p*\rS18/l_S0xIgU"],
    ["fTE\r\rR1f-x9+/g\rxl*xR1f-R+0-g\rr+x10+/+gU"],
    ["fT)\rE9g\r+8x/+g_gU"],
    ["gPfR", function() { return User; }],
    ["0fq", 1.6279, 0.0001],
    ["fE", -0.1487, 0.001],
    ["fE", -0.1497, 0.001],
    ["fE", new Complex(-0.1497, 2.8319), 0.001],
    ["f)", 0, 1e-10],
    ["x", -0.1497, 0.001],
    ["fR"],
    // p85
    ["gPfr"],
    ["fTqx-S4f-S5g\rS6f-S70\r1f*0S2rS3rf*1R2IxR3IxgU"],
    ["fT0U1f-gU"],
    ["fT1R4R5I*R6R7I+UER4R5I*gU"],
    ["fTE\\g\r+g\r1f-*Ex/gU"],
    ["gPf82"],
    ["1\r", 1],
    ["1\r6", 6],
    ["I", new Complex(1, 6)],
    // TODO: takes too long to run ["fq", new Complex(-3.24e-1, 3.82e-1)],
    // TODO ["x", new Complex(7.87e-4, 1.23e-3)],
    ["f74"],
    // p90
    ["gPfr"],
    ["fTqrS4r2fsqg\bS_qStf_1grS2fRSqfRf-S3fRSqfRG1"],
    ["fT0R_qgU"],
    ["fT1f-UES5fT21S+tR4Rt*R2+S6R3\rf/3G41S-t4S/4S*tG2"],
    ["fT4R6fPfRSqfRrfPS3fRSqfRG2G0"],
    ["fT3R6xIUER5-gU"],
    ["fTE\r\\+f-gU"],
    ["gP"],
    ["9\r", 9],
    [".5\r", 0.5],
    ["2_\r", -2],
    [".1I", new Complex(-2, 0.1)],
    ["fqR_q", new MatrixCheck(A, 9, 2, [
        [-2.0, 0.1000],
        [-1.5, 0.1343],
        [-1.0, 0.4484],
        [-0.5, 0.9161],
        [ 0.0, 1.0382],
        [ 0.5, 0.9161],
        [ 1.0, 0.4484],
        [ 1.5, 0.1343],
        [ 2.0, 0.1000]
    ], 0.001)],
    ["g58"],
    // Section 4: Using Matrix Operations
    // p99
    ["2\r3fsqfRf_11Sq2Sq3Sq4Sq5Sq9SqfR"],
    ["2\r3fsEfRf_12SE2SE2SE4SE5SE6SEfR"],
    ["fe)R_qR_E-", new MatrixCheck(C, 2, 3, [[-1, 0, 1], [0, 0, 3]])],
    ["R_)f_8", 3.3166, 0.0001],
    ["R_)f_7", 3],
    // p119
    ["gPfrfT8f_1fT9R0R1g-6g\bg-5efRScfRG9gUgP"],
    ["3\r3fsqR_qStU8R_q", new MatrixCheck(A, 3, 3, [[1, 0, 0], [0, 1, 0], [0, 0, 1]])],
    // p120
    ["gPfrfTqR_qS_^R_ER_^fe)/feEf_6R_^/R_)+gUgP"],
    ["3\r3fsqf_1fR33Sq16Sq72Sq24_Sq10_Sq57_Sq8_Sq4_Sq17_SqfR"],
    ["3\r3fsEf_1fR1SE0SE0SE0SE1SE0SE0SE0SE1SEfR"],
    ["UqR_)", new MatrixCheck(C, 3, 3, [[-9.6666666, -2.6666666, -32], [8, 2.5, 25.5], [2.6666666, 0.6666666, 9]], 0.000001)],
    // p123
    ["gPfrfTq2\rfs)1fsEUER_qR_ER_)fe^/feq-g\rf_8R_Ef_8gU"],
    ["fTEf_1fRRqfRS4fRRqfRS5S5-R5R/4lR21-*+SE1R21-R/4-fRS)fRR21-R/51-fRS)fRR4R5f*)R31-2*R23-2/f0*+SER4U)_fRS)fRR5U)fRS)fRgUgU"],
    ["fT)2/_Eg\r_R23-2/^*gU"],
    ["gP"],
    ["5fsc", 5],
    ["11S2", 11],
    [".05S3", 0.05],
    ["2\r1", 1],
    ["fsq", 1],
    ["fR", 1],
    ["f_1", 1],
    ["3.25Sq", 3.25],
    ["20.5Sq", 20.5],
    ["f84", 2.05e1],
    ["Uq", 1.1677, 0.0001],
    ["r", 1.098, 0.0001],
    ["Rq", 3.5519, 0.0001],
    ["Rq", 2.1556e1, 0.0001],
    ["f74fR"],
    // p128
    ["gPfrgP"],
    ["0fsc", 0],
    ["f_0", 0],
    ["4\r8", 8],
    ["fsq", 8],
    ["f_1", 8],
    ["fR", 8],
    [function() {
        var R1 = 100;
        var R2 = 1e6;
        var R3 = 1e5;
        var wL = 150;
        var wC1 = 800/3;
        var wC2 = 8/3;
        g_Matrix[0].m = new Matrix([
            [R1, wL-wC1, 0, wC1, 0, 0, 0, 0],
            [0, wC1, R2, wL-wC1, -R2, 0, 0, 0],
            [0, 0, -R2, 0, R2, -wC2+wL, 0, -wL],
            [0, 0, 0, 0, 0, -wL, R3, wL-wC2]
        ]);
    }],
    ["R_q", new MatrixCheck(A, 4, 8)],
    ["f+", new MatrixCheck(A, 8, 4)],
    ["f_2", new MatrixCheck(A, 8, 8)],
    ["Se", new MatrixCheck(A, 8, 8)],
    ["\\", new MatrixCheck(A, 8, 8)],
    ["4\r8fsq", 8],
    ["4\r2fsE", 2],
    ["f_1", 2],
    ["10SE", 10],
    ["R_q", new MatrixCheck(A, 4, 8)],
    ["R_E", new MatrixCheck(B, 4, 2)],
    ["f+", new MatrixCheck(B, 8, 1)],
    ["f_2", new MatrixCheck(B, 8, 2)],
    ["fe)", new MatrixCheck(B, 8, 2)],
    ["*", new MatrixCheck(C, 4, 2)],
    ["f_4", new MatrixCheck(C, 2, 4)],
    ["f_2", new MatrixCheck(C, 2, 8)],
    ["1\r8fs)", 8],
    ["Re", new MatrixCheck(C, 1, 8)],
    ["f_4", new MatrixCheck(C, 8, 1)],
    ["g+", new MatrixCheck(C, 4, 2)],
    ["f_1", new MatrixCheck(C, 4, 2)],
    ["f84", new MatrixCheck(C, 4, 2)],
    ["R)", 1.9950e-4, 0.001],
    ["R)", 4.0964e-3, 0.0001],
    ["xg1", 4.1014e-3, 0.0001],
    ["x", 8.7212e1, 0.0001],
    ["R)", -1.4489e-3, 0.0001],
    ["R)", -3.5633e-2, 0.0001],
    ["xg1", 3.5662e-2, 0.0001],
    ["x", -9.2328e1, 0.0001],
    ["R)", -1.4541e-3, 0.0001],
    ["R)", -3.5633e-2, 0.0001],
    ["xg1", 3.5662e-2, 0.0001],
    ["x", -9.2337e1, 0.0001],
    ["R)", 5.3446e-5, 0.0001],
    ["R)", -2.2599e-6, 0.0001],
    ["xg1", 5.3494e-5, 0.0001],
    ["x", -2.4212, 0.0001],
    ["xe5*", 5.3494, 0.0001],
    ["f74fR"],
    // p135
    ["gPfr"],
    ["fTqR_Ef_8gqR_q\rfe)f_5g\rR_Efe^f_5x/R_qxfeEf_6f_8gqRsq-/\r\rR_)fe)/grR_Ef_8gq-g\rgU"],
    ["fTER_qR_^_feEf_6R_^_gU"],
    ["gP"],
    ["f_0"],
    ["11\r3", 3],
    ["fsq", 3],
    ["11\r1", 1],
    ["fsE", 1],
    ["f_1", 1],
    ["fR", 1],
    [function() {
        g_Matrix[0].m = new Matrix([
            [1, 3.9, 3.5],
            [1, 3.7, 4.9],
            [1, 3.3, 5.9],
            [1, 4.5, 5.6],
            [1, 13.1, 4.9],
            [1, 18.9, 5.6],
            [1, 9.2, 8.5],
            [1, 4.6, 7.7],
            [1, 6.1, 7.0],
            [1, 7.8, 6.0],
            [1, 19.3, 5.8]
        ]);
        g_Matrix[1].m = new Matrix([
            [5.4],
            [5.9],
            [4.3],
            [3.3],
            [6.2],
            [11.0],
            [9.1],
            [5.8],
            [6.5],
            [7.6],
            [11.5]
        ]);
    }],
    ["fqf79", 13.51217504, 1e-9],
    ["r", 587.9878252, 1e-9],
    ["rr", 1.689021880, 1e-9],
    ["R^", 1.245864326, 1e-7],
    ["R^", 0.379758235, 1e-8],
    ["R^", 0.413552218, 1e-8],
    ["fE", new MatrixCheck(D, 3, 1)],
    ["R_q", new MatrixCheck(A, 11, 3)],
    ["f_4", new MatrixCheck(A, 3, 11)],
    ["2\r11", 11],
    ["fsq", 11],
    ["R_q", new MatrixCheck(A, 2, 11)],
    ["f_4", new MatrixCheck(A, 11, 2)],
    ["fq", 16.78680552, 1e-9],
    ["r", 584.7131947, 1e-9],
    ["rr", 1.865200613, 1e-9],
    ["R^", 3.701730745, 1e-9],
    ["R^", 0.380094935, 1e-9],
    ["fE", new MatrixCheck(D, 2, 1)],
    ["R_q", new MatrixCheck(A, 11, 2)],
    ["f_4", new MatrixCheck(A, 2, 11)],
    ["1\r11", 11],
    ["fsq", 11],
    ["R_q", new MatrixCheck(A, 1, 11)],
    ["f_4", new MatrixCheck(A, 11, 1)],
    ["fq", 68.08545454, 1e-9],
    ["r", 533.4145457, 1e-9],
    ["rr", 6.808545454, 1e-9],
    ["R^", 6.963636364, 1e-9],
    ["fRf74"],
    // p143
    ["gPfr"],
    ["fTqS21S1fT4RsqxS0fT5R1PR2*fRSqfRG5G4"],
    ["fTERsqxS2f_1fT1g50R2R0RgqRqg-2g40g_g1g\b1f1g60_IrfT2grRqR2R1RgqI*R2R1Sgqf-fRSqfRR1R0g/G2g58S1R2g/gUG1"],
    ["fT)Rsq\rfsqS0S11fs)0S_)e99_Rqg*r_R01Sg)R_)R_qfe)/R01+R0fsq1-1fs)Rqf_1gU"],
    ["gP"],
    ["2fsc", 2],
    ["fR", 2],
    ["f_0", 2],
    ["5\r4", 4],
    ["fsq", 4],
    ["0S_q", 0],
    ["1fq", 1], ["1P", 2], [ "3.9P", 3], ["3.5P", 4], [ "5.4P", 1], ["fE", 5],
    ["1fq", 1], ["1P", 2], [ "3.7P", 3], ["4.9P", 4], [ "5.9P", 1], ["fE", 5],
    ["1fq", 1], ["1P", 2], [ "3.3P", 3], ["5.9P", 4], [ "4.3P", 1], ["fE", 5],
    ["1fq", 1], ["1P", 2], [ "4.5P", 3], ["5.6P", 4], [ "3.3P", 1], ["fE", 5],
    ["1fq", 1], ["1P", 2], ["13.1P", 3], ["4.9P", 4], [ "6.2P", 1], ["fE", 5],
    ["1fq", 1], ["1P", 2], ["18.9P", 3], ["5.6P", 4], ["11.0P", 1], ["fE", 5],
    ["1fq", 1], ["1P", 2], [ "9.2P", 3], ["8.5P", 4], [ "9.1P", 1], ["fE", 5],
    ["1fq", 1], ["1P", 2], [ "4.6P", 3], ["7.7P", 4], [ "5.8P", 1], ["fE", 5],
    ["1fq", 1], ["1P", 2], [ "6.1P", 3], ["7.0P", 4], [ "6.5P", 1], ["fE", 5],
    ["1fq", 1], ["1P", 2], [ "7.8P", 3], ["6.0P", 4], [ "7.6P", 1], ["fE", 5],
    ["1fq", 1], ["1P", 2], ["19.3P", 3], ["5.8P", 4], ["11.5P", 1], ["fE", 5],
    ["f)", 3.6759, 0.0001],
    ["f79", 3.675891055, 1e-9],
    ["gq", 13.51217505, 1e-9],
    ["R)", 1.245864306, 1e-9],
    ["R)", 0.379758235, 1e-9],
    ["R)", 0.413552221, 1e-9],
    ["1fq", 1], ["1P", 2], ["2.5P", 3], ["3.6P", 4], ["4.2P", 1], ["fE", 5],
    ["f)", 3.700256908, 1e-9],
    ["gq", 13.69190119, 1e-9],
    ["R)", 1.581596327, 1e-9],
    ["R)", 0.373826487, 1e-8],
    ["R)", 0.370971848, 1e-9],
    ["f74fR"],
    // p150
    ["gPfr"],
    ["fTqR_qS_ES_)f_4R_ESe+2/S_qf_8S2g\bS3S_)f_1fT0R0R1g-5G3g-7G1xRgE_fRSEfRG0fT1Rgqg_S+3g\r\r+R0\rRgqR1\rRgq-g-3G2_x_xfT2g1g\b4/tfRSEfRG0fT31S)fRSEfRG0R3R/2P2R_E/R_)-R_qfe)f_5R_Efeq*Gq"],
    ["gP4fsc", 4],
    ["fR", 4],
    ["3\rfsq", 3],
    ["f_1", 3],
    ["0Sq1Sq2Sq1Sq2Sq3Sq2Sq3Sq4Sq", 4],
    ["fq", 0.8660, 0.0001],
    ["P", 0.2304, 0.001],
    ["P", 0.1039, 0.001],
    ["P", 0.0060, 0.01],
    ["P", 3.0463e-5, 0.0001],
    ["P", 5.8257e-10, 0.0001],
    ["Rq", -0.8730, 0.0001],
    ["Rq", -9.0006e-10, 0.0001],
    ["Rq", -2.0637e-9 , 0.0001],
    ["Rq", -9.0006e-10, 0.0001],
    ["Rq",  0         , 0.0001],
    ["Rq",  1.0725e-9 , 0.001],
    ["Rq", -2.0637e-9 , 0.0001],
    ["Rq",  1.0725e-9 , 0.001],
    ["Rq",  6.8730, 0.0001],
    ["fR"],
    // p155
    // this sample tends to get stuck in an infinite loop, so skip it
    /*
    ["gPfr"],
    ["fT)S2R_qS_ERsqS0fT4R0S1RER-2SEf50G4Rsq1fs)f_1fT5f\rfRS)fRG5fT6R_)S_^SeR_E/\rf_7/f_1fT7fRR)fR\rg_1g-6G7R_)g\r/R_^Se-f_7f_1PG6"],
    ["gP2fsc", 2],
    ["fR", 2],
    ["3\rfsq", 3],
    ["f_1", 3],
    ["0Sq1Sq2Sq1Sq2Sq3Sq2Sq3Sq4Sq", 4],
    [".8730_", -0.8730],
    ["f)", 0.8982, 0.0001],
    ["P", 0.0001],
    ["P", 2.4e-9],
    ["P", 1e-10],
    ["P", 0],
    ["R)", 1],
    ["R)", 0.2254],
    ["R)", -0.5492],
    ["0F)", 0.8485],
    ["P", 0],
    ["R)", -0.5],
    ["R)", 1],
    ["R)", -0.5],
    ["6.8730f)", 0.7371],
    ["P", 1.9372e-6],
    ["P", 1e-10],
    ["P", 0],
    ["R)", 0.3923],
    ["R)", 0.6961],
    ["R)", 1],
    ["fR"],
    */
    // p163
    ["gPfr"],
    ["fT8R_)S_\\R_qS_)R_\\S_qgU"],
    ["fT7R4R/6S8U\\R_\\S_^R_^g60_f_8g*gU\\R*8S.10S.0R5S7fT6R.1U3fPg60_g-4G5U8R.1S.0R2S*.1f57G6R_qg_G6fT5R6S7fT4U8R.0R+.12/S8U3g60_11Strg-1f5tR8Scf57G4gU"],
    ["fT3R_^fe)*R_q+U8U\\S9R_\\R_^feEf_51\rRgEgU"],
    ["fTq0S6fT21S+6f83U7R6f70fPf_1f83R9PR3R_\\f_8g/GEfPR5R6g-8G2R_)g_G2fTEg49PGE"],
    ["fT\\Rsqfs\\f_1fRRqfRS.2S\\RqS.3f_1S\\+50-_2*f4.2S*.3R.2R_\\fe\\*R.3R+.3-R.2R*.3gU"],
    ["gP13fsc", 13],
    ["g50", 13],
    ["fR", 13],
    ["f_1", 13],
    ["2\r1", 1],
    ["fsq", 1],
    ["15Sq", 15],
    ["Sq", 15],
    ["3S2", 3],
    ["0.1S3", 0.1],
    ["0.05S4", 0.05],
    ["4S5", 4],
    ["fq", "Error 1"],
    ["5S7", 5],
    ["8S5", 8],
    ["P", 9.253e3, 0.0001],
    ["P", 9.259e3, 0.0001],
    ["P", 9.259e3, 0.0001],
    ["P", function() { return Math.abs(1-Stack[0]/7.726e-2) < 0.0001 && Flags[9]; }, 0.0001],
    ["\b", 7.726e-2, 0.0001],
    ["f74", 0.0773, 0.001],
    ["Rq", 16.6661, 0.0001],
    ["Rq", 16.6661, 0.0001],
    ["fRf_0"],

    // miscellaneous tests not covered by user manual
    // complex inverse trig functions
    ["1\r2Isgs", new Complex(1, 2), 1e-9],
    ["1\r2Icgc", new Complex(1, 2), 1e-9],
    ["1\r2Itgt", new Complex(1, 2), 1e-9],
    ["2\r1IfGsgGs", new Complex(2, 1), 1e-9],
    ["2\r1IfGcgGc", new Complex(2, 1), 1e-9],
    ["2\r1IfGtgGt", new Complex(2, 1), 1e-9],
    ["g58"],
    // matrix determinant
    ["2\rfsq"],
    [function() {
        g_Matrix[0].m = new Matrix([
            [6, 3],
            [4, 3]
        ]);
    }],
    ["R_q", new MatrixCheck(A, 2, 2)],
    ["f_9", 6],
    ["3\rfsq"],
    [function() {
        g_Matrix[0].m = new Matrix([
            [-2, 2, -3],
            [-1, 1,  3],
            [ 2, 0, -1]
        ]);
    }],
    ["R_q", new MatrixCheck(A, 3, 3)],
    ["f_9", 18],

    // various particular value tests
    ["g48"],
    // complex sin
    ["0s", new Complex(0, 0)],
    ["p\r2/s", new Complex(1, 0)],
    ["p\r2/_s", new Complex(-1, 0)],
    ["p\r4/s", new Complex(1/Math.sqrt(2), 0)],
    ["p\r6/s", new Complex(0.5, 0), 1e-10],
    // complex tanh
    ["0fGt", new Complex(0, 0)],
    ["5q1+2/lfGt", new Complex(Math.sqrt(5)/5, 0), 1e-10],
    // check that real and complex results match
    ["g58g8"],
    ["1sS01cS11tS2"],
    ["g48"],
    ["1sS31cS41tS5"],
    ["R0R3/", 1],
    ["R1R4/", 1],
    ["R2R5/", 1],

    // http://en.wikipedia.org/wiki/Gamma_function#Particular_values
    ["5\r2/_1-f0", -0.945, 0.001],
    ["3\r2/_1-f0", 2.363, 0.001],
    ["1\r2/_1-f0", -3.545, 0.001],
    ["1\r2/1-f0", 1.772, 0.001],
    ["0f0", 1, 0.001],
    ["3\r2/1-f0", 0.886, 0.001],
    ["1f0", 1, 0.001],
    ["5\r2/1-f0", 1.329, 0.001],
    ["2f0", 2, 0.001],
    ["7\r2/1-f0", 3.323, 0.001],
    ["3f0", 6, 0.001]
];

var TestStart;
var TestIndex;
var TestPass;

function test_log(msg) {
    if (window.console) {
        console.log(msg);
    }
}

function tolerance(r, e, t) {
    if (t === undefined) {
        return r === e;
    } else if (e === 0) {
        return Math.abs(r) < t;
    } else {
        return Math.abs(r / e - 1) < t;
    }
}

function MatrixCheck(label, rows, cols, elements, eps) {
    this.label = label;
    this.rows = rows;
    this.cols = cols;
    this.elements = elements;

    this.check = function(m) {
        if (m.rows !== this.rows || m.cols !== this.cols) {
            return false;
        }
        if (this.elements !== undefined) {
            for (var i = 1; i <= this.rows; i++) {
                for (var j = 1; j <= this.cols; j++) {
                    if (!tolerance(m.get(i, j), this.elements[i-1][j-1], eps)) {
                        alert("matrix check expected " + this.elements[i-1][j-1] + " but got " + m.get(i, j));
                        return false;
                    }
                }
            }
        }
        return true;
    }

    this.toString = function() {
        return "<MatrixCheck " + this.label + " " + this.rows + "," + this.cols + ">";
    };
}

function verify(test, result, resulti, expected) {
    if (expected instanceof MatrixCheck) {
        return result instanceof Descriptor
            && result.label === expected.label
            && expected.check(g_Matrix[result.label]);
    } else if (expected instanceof Complex) {
        if (test.length >= 3) {
            return tolerance(result, expected.re, test[2])
                && tolerance(resulti, expected.im, test[2]);
        } else {
            return result === expected.re && resulti === expected.im;
        }
    } else {
        if (test.length >= 3) {
            return tolerance(result, expected, test[2]);
        } else {
            return result === expected;
        }
    }
}

function start_tests() {
    key('f'); key('7'); key('4');
    key('g'); key('5'); key('8');
    key('f'); key('r');
    //var oldalert = alert;
    //alert = function(msg) { test_log(msg); };
    TestStart = new Date();
    TestIndex = 0;
    TestPass = true;
    run_tests();
}

function run_tests() {
    if (TestIndex < Tests.length) {
        var test = Tests[TestIndex];
        var keys = test[0];
        if (typeof(keys) === "string") {
            test_log(keys);
            for (var i = 0; i < keys.length; i++) {
                key(keys.substr(i, 1), true);
                while (Running) {
                    if (RunTimer !== null) {
                        clearTimeout(RunTimer);
                        RunTimer = null;
                    }
                    var p = PC;
                    if (p === 0) {
                        p = 1;
                    }
                    test_log(sprintf("%03d-%s", p, Program[p].info.keys));
                    step();
                }
            }
        } else if (typeof(keys) === "function") {
            keys();
        }
        if (test.length > 1) {
            var expected = test[1];
            if (typeof(expected) === "string") {
                if (expected !== LcdDisplay) {
                    alert("fail: " + keys + "\nresult: " + LcdDisplay + "\nexpected: " + expected);
                    TestPass = false;
                }
            } else if (typeof(expected) === "function") {
                if (!expected()) {
                    alert("fail: " + keys + "\nresult: " + LcdDisplay + "\nexpected: " + expected);
                    TestPass = false;
                }
            } else {
                if (expected[0] === undefined) {
                    expected = [expected];
                }
                for (var i in expected) {
                    if (!verify(test, Stack[i], StackI[i], expected[i])) {
                        alert("fail: " + keys + "\nresult: " + Stack[i] + "\nexpected: " + expected[i] + "\ndiff: " + Math.abs(Stack[i] / expected[i] - 1));
                        TestPass = false;
                    }
                }
            }
        }
        TestIndex++;
        if (TestPass) {
            setTimeout(run_tests, 0);
        } else {
            alert("fail");
            DisableKeys = false;
        }
    } else {
        //alert = oldalert;
        if (TestPass) {
            var end = new Date();
            alert("pass: " + ((end.getTime() - TestStart.getTime()) / 1000) + " s");
        }
        DisableKeys = false;
    }
}
